home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
ada
/
gwuada_6.zip
/
PARSER.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-10-24
|
24KB
|
927 lines
/*
GWAda Development Environment for 386/486 PCs
Copyright (C) 1993, Arthur Vargas Lopes & Michael Bliss Feldman
vlopes@vortex.ufrgs.br mfeldman@seas.gwu.edu
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* Parser.c */
#include "externs.h"
#include "defines.h"
char *strupr(char *string);
char *strcat(char *string1, const char *string2);
typedef struct {
char yytext[AVL_MAX_LINEL + 1];
AVL_LINE_PTR temp; /* Full source line */
int yyleng;
int code;
int line_no;
int line_col;
} TOKEN_TYPE;
typedef struct { /* I/O structure */
char buffer[AVL_MAX_LINEL + 40];
char last_token[AVL_MAX_LINEL + 1];
char decimal_point;
int size;
int ibuf;
int line_no;
int look_ahead;
int look_ahead_c[5];
int look_ahead_t;
TOKEN_TYPE look_ahead_tcode[3];
} IO_TYPE;
IO_TYPE io_size;
#include "bsearch.c"
void AVL_START_UP()
{
int ch;
char msg[100];
AVL_EDIT_WINDOW_PTR w;
w = &avl_windows[avl_window];
io_size.decimal_point = '.';
io_size.look_ahead = 0;
io_size.line_no = w -> current_line -> line_no;
io_size.ibuf = w -> txt_col;
io_size.look_ahead_t = 0;
sprintf(io_size.buffer, w -> current_line -> line);
io_size.size = strlen(io_size.buffer);
sprintf(io_size.last_token,"THIS_IS_THE_END_OF_THE_FILE");
}
int AVL_NEXT()
{
AVL_EDIT_WINDOW_PTR w;
AVL_LINE_PTR temp, temp2;
int ch;
w = &avl_windows[avl_window];
if (io_size.look_ahead) { /* There is a look ahead char in the queue */
ch = io_size.look_ahead_c[0];
io_size.look_ahead_c[0] = io_size.look_ahead_c[1];
io_size.look_ahead_c[1] = io_size.look_ahead_c[2];
io_size.look_ahead_c[2] = io_size.look_ahead_c[3];
io_size.look_ahead_c[3] = io_size.look_ahead_c[4];
io_size.look_ahead -= 1;
return ch;
}
if (io_size.ibuf >= io_size.size) {
if (w -> current_line -> next == w -> head)
sprintf(io_size.buffer," \n THIS_IS_THE_END_OF_THE_FILE \" \n THIS_IS_THE_END_OF_THE_FILE ");
else {
w -> current_line = w -> current_line -> next;
sprintf(io_size.buffer,"%s\n", w -> current_line -> line);
io_size.line_no = w -> current_line -> line_no;
}
io_size.size = strlen(io_size.buffer);
io_size.ibuf = 0;
}
ch = io_size.buffer[io_size.ibuf++];
if (ch == 26) ch = ' ';
if (ch == 0) return ' ';
return ch;
}
void BACK(int ch)
{
if (io_size.look_ahead > 4) {
AVL_ERROR("Too many look ahead bytes. SYSTEM ERROR...");
exit(1);
}
io_size.look_ahead_c[io_size.look_ahead++] = ch;
}
int IS_DIGIT(int ch, int base, int *n)
{
int num;
char msg[40];
*n = 0;
if (ch >= 'A' && ch <= 'F')
num = ch - 'A' + 11;
else if (ch >= '0' && ch <= '9')
num = ch - '0';
else
return 0;
sprintf(msg,"%c in %d base ", ch, base);
if (num < 0 || num >= base)
AVL_ERROR(strcat("Based number with invalid digit ==> ",msg));
*n = num;
return 1;
}
void BACK_T(TOKEN_TYPE tk)
{
if (io_size.look_ahead_t > 2) {
AVL_ERROR("Too many look ahead tokens. SYSTEM ERROR...");
exit(1);
}
io_size.look_ahead_tcode[io_size.look_ahead_t++] = tk;
}
TOKEN_TYPE AVL_SCAN()
{
int ch, lch;
int is_real = 0;
int is_based = 0;
int base = 10;
int is_expo = 0;
int string_mark;
int temp;
static TOKEN_TYPE tk;
AVL_EDIT_WINDOW_PTR w;
char yytext[AVL_MAX_LINEL + 1];
w = &avl_windows[avl_window];
if (io_size.look_ahead_t) {
tk = io_size.look_ahead_tcode[0];
io_size.look_ahead_tcode[0] = io_size.look_ahead_tcode[1];
io_size.look_ahead_tcode[1] = io_size.look_ahead_tcode[2];
io_size.look_ahead_t -= 1;
return tk;
}
tk.yyleng = 0;
tk.yytext[0] = '\0';
again:
/* First skip blanks */
while (isspace(ch = AVL_NEXT()));
/* Test comment */
if (ch == '-') {
ch = AVL_NEXT();
if (ch == '-') { /* Now reject til end of line */
while ((ch = AVL_NEXT()) != '\n');
goto again;
}
BACK('-');
BACK(ch);
}
else BACK(ch);
ch = AVL_NEXT();
/* Now let's see what we got */
tk.line_no = io_size.line_no;
tk.line_col = io_size.ibuf;
tk.temp = w -> current_line;
if (isalpha(ch)) { /* Got an object's name */
lch = ' ';
do {
if (tk.yyleng >= AVL_MAX_LINEL) {
tk.yytext[tk.yyleng] = '\0';
AVL_ERROR(strcat("Symbol too long => ", tk.yytext));
}
if (ch == '-' && lch == '-') {
tk.yytext[tk.yyleng] = '\0';
AVL_ERROR(strcat("Do not repeat _ ==> ", tk.yytext));
}
tk.yytext[tk.yyleng++] = ch;
lch = ch;
ch = AVL_NEXT();
} while (isalpha(ch) || isdigit(ch) || ch == '_');
tk.yytext[tk.yyleng] = '\0';
strcpy(yytext,tk.yytext);
strupr(yytext);
if (lch == '_')
AVL_ERROR(strcat("_ can't terminate an object's name ==> ", tk.yytext));
BACK(ch);
if (tk.code == XATTMARK) { /* See if previous token was an ' */
lch = IS_ATT(yytext);
if (lch == 0)
AVL_ERROR(strcat("Invalid attribute ==> ", tk.yytext));
tk.code = lch;
}
else {
if (!strcmp(yytext,"REM"))
tk.code = XMULT;
else if (!strcmp(yytext,"MOD"))
tk.code = XMULT;
else if (!strcmp(yytext,"AND"))
tk.code = XLOG;
else if (!strcmp(yytext,"OR"))
tk.code = XLOG;
else
tk.code = IS_KEYWORD(yytext);
if (tk.code == 0)
if (strcmp(io_size.last_token,yytext))
tk.code = XID;
}
return tk;
}
if (isdigit(ch)) { /* Got a numeric literal */
lch = ' ';
do {
if (tk.yyleng >= AVL_MAX_LINEL) {
tk.yytext[tk.yyleng] = '\0';
AVL_ERROR(strcat("Numeric literal too long ==> ", tk.yytext));
}
if (lch == ch && ch == '_') {
tk.yytext[tk.yyleng] = '\0';
AVL_ERROR(strcat("Two _ repeated within numeric literal ==> ", tk.yytext));
}
if (ch != '_')
tk.yytext[tk.yyleng++] = ch;
lch = ch;
ch = AVL_NEXT();
} while (isdigit(ch) || ch == '_');
if (lch == '_') {
tk.yytext[tk.yyleng] = '\0';
AVL_ERROR(strcat("_ can't terminate an integer ==> ", tk.yytext));
}
if (ch == ':' || ch == '#') { /* Got a based number */
is_based = ch;
tk.yytext[tk.yyleng] = '\0';
base = atoi(tk.yytext);
if (base < 2 || base > 16)
AVL_ERROR(strcat("Based literal with invalid base ==> ", tk.yytext));
tk.yyleng = 0;
ch = AVL_NEXT();
if (!IS_DIGIT(ch,base,&temp))
AVL_ERROR("A digit was expected");
lch = ' ';
do {
if (lch == ch && ch == '_') {
tk.yytext[tk.yyleng] = '\0';
AVL_ERROR(strcat("Two _ repeated within numeric literal ==> ", tk.yytext));
}
if (ch != '_')
tk.yytext[tk.yyleng++] = ch;
lch = ch;
ch = AVL_NEXT();
} while (IS_DIGIT(ch,base,&temp) || ch == '_');
if (lch == '_') {
tk.yytext[tk.yyleng] = '\0';
AVL_ERROR(strcat("_ can't terminate an integer ==> ", tk.yytext));
}
}
if (ch == io_size.decimal_point) { /* Got a real number? */
if (ch == '.') {
ch = AVL_NEXT();
if (ch == '.') {
BACK('.');
BACK('.');
tk.yytext[tk.yyleng] = '\0';
tk.code = XINTEGERLIT;
return tk;
}
BACK(ch);
}
is_real = 1;
tk.yytext[tk.yyleng++] = '.';
ch = AVL_NEXT();
if (!IS_DIGIT(ch,base,&temp)) {
tk.yytext[tk.yyleng] = '\0';
AVL_ERROR(strcat("A digit should follow a decimal point ==> ", tk.yytext));
}
lch = ' ';
do {
if (lch == ch && ch == '_') {